package com.itany.corejava.code16_反射;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author Miss Chen
 * @version 1.0
 * @date 2024年08月12日14:13
 */
public class Test05_Method {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class c=User.class;
        // 1.获取当前类以及其祖先类中所有public修饰的方法
        Method[] methods=c.getMethods();
        System.out.println(Arrays.toString(methods));

        // 2.获取当前类中所有方法,不区分修饰符
        Method[] delaredMethods=c.getDeclaredMethods();
        System.out.println(Arrays.toString(delaredMethods));

        // 3.获取当前类以及祖先类中指定参数的public修饰的方法
        Method sumMethod=c.getMethod("sum",int.class,int.class);
        System.out.println(sumMethod);
        //无法访问private修饰的方法
        // Method addMethod=c.getMethod("add",double.class,double.class);
        // System.out.println(addMethod);

        //访问父类中方法
        Method reduceMethod=c.getMethod("reduce",int.class,int.class);
        System.out.println(reduceMethod);

        // 4.获取当前类中任意方法，不区分修饰符
        Method addMethod=c.getDeclaredMethod("add",double.class,double.class);
        System.out.println(addMethod);

        //无法访问父类中的方法
        // Method reduceMethod2=c.getDeclaredMethod("reduce",int.class,int.class);
        // System.out.println(reduceMethod2);

        System.out.println(addMethod.getName());
        System.out.println(reduceMethod.getName());
        System.out.println(sumMethod.getName());

        User user=new User();
        int sum= (int) sumMethod.invoke(user,2,8);
        System.out.println(sumMethod.getName()+"方法执行成功，方法的返回值是:"+sum);


        //无法直接执行private修饰的方法，需要取消权限检查
        addMethod.setAccessible(true);
        double add= (double) addMethod.invoke(user,10,20);
        System.out.println(addMethod.getName()+"方法执行成功，方法的返回值是:"+add);

            // 总结:
            // 1.反射的作用
            //         获取任意一个类中的所有信息
            //         结合配置文件动态创建对象
            //
            // 2.获取class字节码文件对象的三种方式
            // 类名.class
            // 对象.getClass()
            // 3.如何获取构造方法、成员属性、成员方法
    }
}
